package com.community.windy.service;

import com.community.windy.dao.elasticsearch.DiscussPostRepository;
import com.community.windy.entity.DiscussPost;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ElasticsearchService {

    @Autowired
    private DiscussPostRepository discussPostRepository;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;


    public void saveDiscussPost(DiscussPost post){
        discussPostRepository.save(post);
    }

    public void deleteDiscussPost(int id){
        discussPostRepository.deleteById(id);
    }

    public Page<DiscussPost> searchDiscussPost(String keyword, int current, int limit){
        PageRequest page = PageRequest.of(current,limit);
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(keyword,"title","content"))
                .withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSorts(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSorts(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(page)
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
                ).build();
        SearchHits<DiscussPost> hits = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);
        if(hits.getTotalHits()<=0){
            return new PageImpl<>(new ArrayList(),page,0);
        }
        List<DiscussPost> list = new ArrayList<>();
        for (SearchHit<DiscussPost> hit: hits){
            DiscussPost content =  hit.getContent();
            Map<String,List<String>> highlightFields = hit.getHighlightFields();
            for (Map.Entry<String,List<String>>  stringHighlightFieldEntry:highlightFields.entrySet()){
                String key = stringHighlightFieldEntry.getKey();
                if(StringUtils.equals(key,"title")){
                    List<String> fragments = stringHighlightFieldEntry.getValue();
                    StringBuilder sb = new StringBuilder();
                    for (String fragment: fragments){
                        sb.append(fragment);
                    }
                    content.setTitle(sb.toString());
                }
                if (StringUtils.equals(key,"content")){
                    List<String> fragments = stringHighlightFieldEntry.getValue();
                    StringBuilder sb = new StringBuilder();
                    for (String fragment: fragments){
                        sb.append(fragment);
                    }
                    content.setContent(sb.toString());
                }
                list.add(content);
            }
        }

        Page<DiscussPost> pageList = new PageImpl(list,page,hits.getTotalHits());
        return pageList;
    }
}
